﻿using BCCommon;
using BCCommon.Enums;
using BCData.Trading.Purchase.GoodsPurchaseItem;
using BCDto.Trading.Purchase.GoodsPurchaseItem;
using BCEntity.Trading.Purchase.GoodsPurchaseItem;
using BCEntity.Common.EntityNameConst;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BCData.Trading.SaleGoods.SaleGoodsNorm;
using BCData.Trading.Vendor.Vendor;

namespace BCService.Trading.Purchase.GoodsPurchaseItem
{
    public class GoodsPurchaseItemService : IGoodsPurchaseItemService
    {
        private readonly IDatabaseContext databaseContext;
        private readonly IApplicationContextService applicationContextService;
        private readonly IRedisService redisService;
        private readonly IGoodsPurchaseItemData goodsPurchaseItemData;
        private readonly ISaleGoodsNormData saleGoodsNormData;
        private readonly IVendorData vendorData;
        private readonly string key = string.Format("{0}", EntityNameConst.GoodsPurchaseItemEntity);

        public GoodsPurchaseItemService(IDatabaseContext databaseContext,
            IApplicationContextService applicationContextService,
            IRedisService redisService,
            IGoodsPurchaseItemData goodsPurchaseItemData,
            ISaleGoodsNormData saleGoodsNormData,
            IVendorData vendorData)
        {
            this.databaseContext = databaseContext;
            this.applicationContextService = applicationContextService;
            this.redisService = redisService;
            this.goodsPurchaseItemData = goodsPurchaseItemData;
            this.saleGoodsNormData = saleGoodsNormData;
            this.vendorData = vendorData;
        }

        #region 检查商品采购项是否存在
        public bool Exists(long goodsPurchaseItemId)
        {
            return this.goodsPurchaseItemData.Exists(goodsPurchaseItemId).GetAwaiter().GetResult();
        }
        #endregion

        #region 添加商品采购项
        public GoodsPurchaseItemDto Add(GoodsPurchaseItemRequestDto requestDto)
        {
            if (!this.saleGoodsNormData.Exists(requestDto.SaleGoodsNormId).Result)
            {
                throw new ArgumentException("此商品规格不存在!");
            }

            if (!this.vendorData.Exists(requestDto.VendorId).Result)
            {
                throw new ArgumentException("此供应商信息不存在!");
            }

            var goodsNormEntity = this.saleGoodsNormData.GetEntity(requestDto.SaleGoodsNormId).Result;
            var vendorEntity = this.vendorData.GetEntity(requestDto.VendorId).Result;
            var entity = requestDto.As<GoodsPurchaseItemEntity>();
            entity.SaleGoodsCategoryId = goodsNormEntity.SaleGoodsCategoryId;
            entity.CategoryName = goodsNormEntity.CategoryName;
            entity.SaleGoodsId = goodsNormEntity.SaleGoodsId;
            entity.GoodsName = goodsNormEntity.GoodsName;
            entity.Sku = goodsNormEntity.Sku;
            entity.SaleGoodsNormId = goodsNormEntity.SaleGoodsNormId;
            entity.NormName = goodsNormEntity.NormName;
            entity.NormNo = goodsNormEntity.NormNo;
            entity.VendorCategoryId = vendorEntity.VendorCategoryId;
            entity.VendorCategoryName = vendorEntity.VendorCategoryName;
            entity.VendorId = vendorEntity.VendorId;
            entity.VendorName = vendorEntity.VendorName;
            entity.PurchaseUnit = goodsNormEntity.SaleUnit;
            entity.CreateAdminName = applicationContextService.Admin.FullName;
            entity.CreateAdminId = applicationContextService.Admin.AdminId;
            
            return this.goodsPurchaseItemData.Add(entity).GetAwaiter().GetResult().As<GoodsPurchaseItemDto>();
        }
        #endregion

        #region 修改商品采购项
        public GoodsPurchaseItemDto Update(GoodsPurchaseItemPutDto putDto)
        {
            if (!this.Exists(putDto.GoodsPurchaseItemId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            if (!this.saleGoodsNormData.Exists(putDto.SaleGoodsNormId).Result)
            {
                throw new ArgumentException("此商品规格不存在!");
            }

            if (!this.vendorData.Exists(putDto.VendorId).Result)
            {
                throw new ArgumentException("此供应商信息不存在!");
            }
            var goodsNormEntity = this.saleGoodsNormData.GetEntity(putDto.SaleGoodsNormId).Result;
            var vendorEntity = this.vendorData.GetEntity(putDto.VendorId).Result;
            var entity = putDto.As<GoodsPurchaseItemEntity>();
            entity.SaleGoodsCategoryId = goodsNormEntity.SaleGoodsCategoryId;
            entity.CategoryName = goodsNormEntity.CategoryName;
            entity.SaleGoodsId = goodsNormEntity.SaleGoodsId;
            entity.GoodsName = goodsNormEntity.GoodsName;
            entity.Sku = goodsNormEntity.Sku;
            entity.SaleGoodsNormId = goodsNormEntity.SaleGoodsNormId;
            entity.NormName = goodsNormEntity.NormName;
            entity.NormNo = goodsNormEntity.NormNo;
            entity.VendorCategoryId = vendorEntity.VendorCategoryId;
            entity.VendorCategoryName = vendorEntity.VendorCategoryName;
            entity.VendorId = vendorEntity.VendorId;
            entity.VendorName = vendorEntity.VendorName;
            entity.PurchaseUnit = goodsNormEntity.SaleUnit;
            entity.EditAdminName = applicationContextService.Admin.FullName;
            entity.EditAdminId = applicationContextService.Admin.AdminId;
            var result = this.goodsPurchaseItemData.Update(entity).GetAwaiter().GetResult().As<GoodsPurchaseItemDto>();
            string cacheKey = this.redisService.GetKey(key);
            this.redisService.DeleteMultipleKey(cacheKey,false);

            return result;
        }
        #endregion

        #region 删除商品采购项
        public bool Delete(long goodsPurchaseItemId)
        {
            if (!this.Exists(goodsPurchaseItemId))
            {
                throw new ArgumentException("此记录不存在!");
            }

            var result = this.goodsPurchaseItemData.Delete(goodsPurchaseItemId).GetAwaiter().GetResult();
            string cacheKey = this.redisService.GetKey(key);
            this.redisService.DeleteMultipleKey(cacheKey, false);
            return result;
        }
        #endregion

        #region 获取商品采购项
        public GoodsPurchaseItemDto Get(long goodsPurchaseItemId)
        {
            string cacheKey = this.redisService.GetKey(key, goodsPurchaseItemId);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.goodsPurchaseItemData.GetEntity(goodsPurchaseItemId).GetAwaiter().GetResult();
                return data;
            }, TimeSpan.FromMinutes(30));
            return result.As<GoodsPurchaseItemDto>();
        }
        #endregion

        #region 获取商品采购项列表
        public IEnumerable<GoodsPurchaseItemDto> GetList(long adminId, bool? hasTask)
        {
            string cacheKey = this.redisService.GetKey(key, adminId, hasTask);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                return this.goodsPurchaseItemData.GetList(adminId, hasTask).GetAwaiter().GetResult();
            }, TimeSpan.FromMinutes(30));
            return result.As<IEnumerable<GoodsPurchaseItemDto>>();
        }
        #endregion

        #region 获取商品采购项分页
        public PageableList<GoodsPurchaseItemDto> Query(string categoryName, string goodsName, string sku, string vendorName, string adminName, long? adminId,int? vendorId, bool? hasTask, DateTime? start, DateTime? end, string sortName, bool? ascending, int pageIndex, int pageSize)
        {
            string cacheKey = this.redisService.GetKey(key, categoryName, goodsName, sku, vendorName, adminName, adminId, vendorId, hasTask, start, end, sortName, ascending, pageIndex, pageSize);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var data = this.goodsPurchaseItemData.Query(categoryName, goodsName, sku, vendorName, adminName, adminId, vendorId, hasTask, start, end, sortName, ascending, pageIndex, pageSize).GetAwaiter().GetResult();
                return new PageableList<GoodsPurchaseItemDto>
                {
                    Count = data.Item2,
                    Items = data.Item1.As<IEnumerable<GoodsPurchaseItemDto>>(),
                    PageIndex = pageIndex,
                    PageSize = pageSize,
                    ServerTime = DateTime.Now
                };
            }, TimeSpan.FromMinutes(30));

            return result;
        }
        #endregion

        #region  获取采购项存在的供应商列表
        public IEnumerable<GoodsPurchaseItemDto> GetPurchaseItemsVendorList()
        {
            return this.goodsPurchaseItemData.GetPurchaseItemsVendorList().Result.As<IEnumerable<GoodsPurchaseItemDto>>();
        }
        #endregion
    }
}